implement ktrans;

include "sys.m";
include "draw.m";

anjal:= array[] of {
	("zuu",	""),
	("zu",	""),
	("zoo",	""),
	("zo",	""),
	("zii",	""),
	("zi",	""),
	("zhuu",	""),
	("zhu",	""),
	("zhoo",	""),
	("zho",	""),
	("zhii",	""),
	("zhi",	""),
	("zhee",	""),
	("zhe",	""),
	("zhau",	""),
	("zhai",	""),
	("zhaa",	""),
	("zha",	""),
	("zhU",	""),
	("zhO",	""),
	("zhI",	""),
	("zhE",	""),
	("zhA",	""),
	("zh",	""),
	("zee",	""),
	("ze",	""),
	("zau",	""),
	("zai",	""),
	("zaa",	""),
	("za",	""),
	("zU",	""),
	("zO",	""),
	("zI",	""),
	("zE",	""),
	("zA",	""),
	("z",	""),
	("yuu",	""),
	("yu",	""),
	("yoo",	""),
	("yo",	""),
	("yii",	""),
	("yi",	""),
	("yee",	""),
	("ye",	""),
	("yau",	""),
	("yai",	""),
	("yaa",	""),
	("ya",	""),
	("yU",	""),
	("yO",	""),
	("yI",	""),
	("yE",	""),
	("yA",	""),
	("y",	""),
	("xuu",	""),
	("xu",	""),
	("xoo",	""),
	("xo",	""),
	("xii",	""),
	("xi",	""),
	("xee",	""),
	("xe",	""),
	("xau",	""),
	("xai",	""),
	("xaa",	""),
	("xa",	""),
	("xU",	""),
	("xO",	""),
	("xI",	""),
	("xE",	""),
	("xA",	""),
	("x",	""),
	("wuu",	""),
	("wu",	""),
	("woo",	""),
	("wo",	""),
	("wii",	""),
	("wi",	""),
	("wee",	""),
	("we",	""),
	("wau",	""),
	("wai",	""),
	("waa",	""),
	("wa",	""),
	("wU",	""),
	("wO",	""),
	("wI",	""),
	("wE",	""),
	("wA",	""),
	("w",	""),
	("vuu",	""),
	("vu",	""),
	("voo",	""),
	("vo",	""),
	("vii",	""),
	("vi",	""),
	("vee",	""),
	("ve",	""),
	("vau",	""),
	("vai",	""),
	("vaa",	""),
	("va",	""),
	("vU",	""),
	("vO",	""),
	("vI",	""),
	("vE",	""),
	("vA",	""),
	("v",	""),
	("uu",		""),
	("u",		""),
	("tuu",	""),
	("tu",	""),
	("tthuu",	""),
	("tthu",	""),
	("tthoo",	""),
	("ttho",	""),
	("tthii",	""),
	("tthi",	""),
	("tthee",	""),
	("tthe",	""),
	("tthau",	""),
	("tthai",	""),
	("tthaa",	""),
	("ttha",	""),
	("tthU",	""),
	("tthO",	""),
	("tthI",	""),
	("tthE",	""),
	("tthA",	""),
	("tth",	""),
	("truu",	""),
	("tru",	""),
	("troo",	""),
	("tro",	""),
	("trii",	""),
	("tri",	""),
	("tree",	""),
	("tre",	""),
	("trau",	""),
	("trai",	""),
	("traa",	""),
	("tra",	""),
	("trU",	""),
	("trO",	""),
	("trI",	""),
	("trE",	""),
	("trA",	""),
	("tr",	""),
	("too",	""),
	("to",	""),
	("tii",	""),
	("ti",	""),
	("thuu",	""),
	("thu",	""),
	("thoo",	""),
	("tho",	""),
	("thii",	""),
	("thi",	""),
	("thee",	""),
	("the",	""),
	("thau",	""),
	("thai",	""),
	("thaa",	""),
	("tha",	""),
	("thU",	""),
	("thO",	""),
	("thI",	""),
	("thE",	""),
	("thA",	""),
	("th",	""),
	("tee",	""),
	("te",	""),
	("tau",	""),
	("tai",	""),
	("taa",	""),
	("ta",	""),
	("tU",	""),
	("tO",	""),
	("tI",	""),
	("tE",	""),
	("tA",	""),
	("t",	""),
	("suu",	""),
	("su",	""),
	("sri",	""),
	("soo",	""),
	("so",	""),
	("sii",	""),
	("si",	""),
	("shuu",	""),
	("shu",	""),
	("shoo",	""),
	("sho",	""),
	("shii",	""),
	("shi",	""),
	("shee",	""),
	("she",	""),
	("shau",	""),
	("shai",	""),
	("shaa",	""),
	("sha",	""),
	("shU",	""),
	("shO",	""),
	("shI",	""),
	("shE",	""),
	("shA",	""),
	("sh",	""),
	("see",	""),
	("se",	""),
	("sau",	""),
	("sai",	""),
	("saa",	""),
	("sa",	""),
	("sU",	""),
	("sO",	""),
	("sI",	""),
	("sE",	""),
	("sA",	""),
	("s",	""),
	("ruu",	""),
	("ru",	""),
	("roo",	""),
	("ro",	""),
	("rii",	""),
	("ri",	""),
	("ree",	""),
	("re",	""),
	("rau",	""),
	("rai",	""),
	("raa",	""),
	("ra",	""),
	("rU",	""),
	("rO",	""),
	("rI",	""),
	("rE",	""),
	("rA",	""),
	("r",	""),
	("q",		""),
	("puu",	""),
	("pu",	""),
	("poo",	""),
	("po",	""),
	("pii",	""),
	("pi",	""),
	("pee",	""),
	("pe",	""),
	("pau",	""),
	("pai",	""),
	("paa",	""),
	("pa",	""),
	("pU",	""),
	("pO",	""),
	("pI",	""),
	("pE",	""),
	("pA",	""),
	("p",	""),
	("oo",		""),
	("o",		""),
	("nuu",	""),
	("nu",	""),
	("nthuu",	""),
	("nthu",	""),
	("nthoo",	""),
	("ntho",	""),
	("nthii",	""),
	("nthi",	""),
	("nthee",	""),
	("nthe",	""),
	("nthau",	""),
	("nthai",	""),
	("nthaa",	""),
	("ntha",	""),
	("nthU",	""),
	("nthO",	""),
	("nthI",	""),
	("nthE",	""),
	("nthA",	""),
	("nth",	""),
	("noo",	""),
	("no",	""),
	("njuu",	""),
	("nju",	""),
	("njoo",	""),
	("njo",	""),
	("njjuu",	""),
	("njju",	""),
	("njjoo",	""),
	("njjo",	""),
	("njjii",	""),
	("njji",	""),
	("njjee",	""),
	("njje",	""),
	("njjau",	""),
	("njjai",	""),
	("njjaa",	""),
	("njja",	""),
	("njjU",	""),
	("njjO",	""),
	("njjI",	""),
	("njjE",	""),
	("njjA",	""),
	("njj",	""),
	("njii",	""),
	("nji",	""),
	("njee",	""),
	("nje",	""),
	("njau",	""),
	("njai",	""),
	("njaa",	""),
	("nja",	""),
	("njU",	""),
	("njO",	""),
	("njI",	""),
	("njE",	""),
	("njA",	""),
	("nj",	""),
	("nii",	""),
	("ni",	""),
	("nguu",	""),
	("ngu",	""),
	("ngoo",	""),
	("ngo",	""),
	("ngii",	""),
	("ngi",	""),
	("ngee",	""),
	("nge",	""),
	("ngau",	""),
	("ngai",	""),
	("ngaa",	""),
	("nga",	""),
	("ngU",	""),
	("ngO",	""),
	("ngI",	""),
	("ngE",	""),
	("ngA",	""),
	("ng",	""),
	("nee",	""),
	("ne",	""),
	("nduu",	""),
	("ndu",	""),
	("ndruu",	""),
	("ndru",	""),
	("ndroo",	""),
	("ndro",	""),
	("ndrii",	""),
	("ndri",	""),
	("ndree",	""),
	("ndre",	""),
	("ndrau",	""),
	("ndrai",	""),
	("ndraa",	""),
	("ndra",	""),
	("ndrU",	""),
	("ndrO",	""),
	("ndrI",	""),
	("ndrE",	""),
	("ndrA",	""),
	("ndr",	""),
	("ndoo",	""),
	("ndo",	""),
	("ndii",	""),
	("ndi",	""),
	("ndee",	""),
	("nde",	""),
	("ndau",	""),
	("ndai",	""),
	("ndaa",	""),
	("nda",	""),
	("ndU",	""),
	("ndO",	""),
	("ndI",	""),
	("ndE",	""),
	("ndA",	""),
	("nd",	""),
	("nau",	""),
	("nai",	""),
	("naa",	""),
	("na",	""),
	("nU",	""),
	("nO",	""),
	("nI",	""),
	("nE",	""),
	("nA",	""),
	("n-uu",	""),
	("n-u",	""),
	("n-oo",	""),
	("n-o",	""),
	("n-ii",	""),
	("n-i",	""),
	("n-ee",	""),
	("n-e",	""),
	("n-au",	""),
	("n-ai",	""),
	("n-aa",	""),
	("n-a",	""),
	("n-U",	""),
	("n-O",	""),
	("n-I",	""),
	("n-E",	""),
	("n-A",	""),
	("n-",	""),
	("n",	""),
	("muu",	""),
	("mu",	""),
	("moo",	""),
	("mo",	""),
	("mii",	""),
	("mi",	""),
	("mee",	""),
	("me",	""),
	("mau",	""),
	("mai",	""),
	("maa",	""),
	("ma",	""),
	("mU",	""),
	("mO",	""),
	("mI",	""),
	("mE",	""),
	("mA",	""),
	("m",	""),
	("luu",	""),
	("lu",	""),
	("loo",	""),
	("lo",	""),
	("lii",	""),
	("li",	""),
	("lee",	""),
	("le",	""),
	("lau",	""),
	("lai",	""),
	("laa",	""),
	("la",	""),
	("lU",	""),
	("lO",	""),
	("lI",	""),
	("lE",	""),
	("lA",	""),
	("l",	""),
	("kuu",	""),
	("ku",	""),
	("koo",	""),
	("ko",	""),
	("kii",	""),
	("ki",	""),
	("kee",	""),
	("ke",	""),
	("kau",	""),
	("kai",	""),
	("kaa",	""),
	("ka",	""),
	("kU",	""),
	("kO",	""),
	("kI",	""),
	("kE",	""),
	("kA",	""),
	("k",	""),
	("juu",	""),
	("ju",	""),
	("joo",	""),
	("jo",	""),
	("jii",	""),
	("ji",	""),
	("jee",	""),
	("je",	""),
	("jau",	""),
	("jai",	""),
	("jaa",	""),
	("ja",	""),
	("jU",	""),
	("jO",	""),
	("jI",	""),
	("jE",	""),
	("jA",	""),
	("j",	""),
	("ii",		""),
	("i",		""),
	("huu",	""),
	("hu",	""),
	("hoo",	""),
	("ho",	""),
	("hii",	""),
	("hi",	""),
	("hee",	""),
	("he",	""),
	("hau",	""),
	("hai",	""),
	("haa",	""),
	("ha",	""),
	("hU",	""),
	("hO",	""),
	("hI",	""),
	("hE",	""),
	("hA",	""),
	("h",	""),
	("guu",	""),
	("gu",	""),
	("goo",	""),
	("go",	""),
	("gii",	""),
	("gi",	""),
	("gee",	""),
	("ge",	""),
	("gau",	""),
	("gai",	""),
	("gaa",	""),
	("ga",	""),
	("gU",	""),
	("gO",	""),
	("gI",	""),
	("gE",	""),
	("gA",	""),
	("g",	""),
	("ee",		""),
	("e",		""),
	("duu",	""),
	("du",	""),
	("doo",	""),
	("do",	""),
	("dii",	""),
	("di",	""),
	("dhuu",	""),
	("dhu",	""),
	("dhoo",	""),
	("dho",	""),
	("dhii",	""),
	("dhi",	""),
	("dhee",	""),
	("dhe",	""),
	("dhau",	""),
	("dhai",	""),
	("dhaa",	""),
	("dha",	""),
	("dhU",	""),
	("dhO",	""),
	("dhI",	""),
	("dhE",	""),
	("dhA",	""),
	("dh",	""),
	("dee",	""),
	("de",	""),
	("dau",	""),
	("dai",	""),
	("daa",	""),
	("da",	""),
	("dU",	""),
	("dO",	""),
	("dI",	""),
	("dE",	""),
	("dA",	""),
	("d",	""),
	("chuu",	""),
	("chu",	""),
	("choo",	""),
	("cho",	""),
	("chii",	""),
	("chi",	""),
	("chee",	""),
	("che",	""),
	("chau",	""),
	("chai",	""),
	("chaa",	""),
	("cha",	""),
	("chU",	""),
	("chO",	""),
	("chI",	""),
	("chE",	""),
	("chA",	""),
	("ch",	""),
	("buu",	""),
	("bu",	""),
	("boo",	""),
	("bo",	""),
	("bii",	""),
	("bi",	""),
	("bee",	""),
	("be",	""),
	("bau",	""),
	("bai",	""),
	("baa",	""),
	("ba",	""),
	("bU",	""),
	("bO",	""),
	("bI",	""),
	("bE",	""),
	("bA",	""),
	("b",	""),
	("au",	""),
	("ai",		""),
	("aa",		""),
	("a",		""),
	("\tnuu",	"\t"),
	("\tnu",	"\t"),
	("\tnoo",	"\t"),
	("\tno",	"\t"),
	("\tnii",	"\t"),
	("\tni",	"\t"),
	("\tnee",	"\t"),
	("\tne",	"\t"),
	("\tnau",	"\t"),
	("\tnai",	"\t"),
	("\tnaa",	"\t"),
	("\tna",	"\t"),
	("\tnU",	"\t"),
	("\tnO",	"\t"),
	("\tnI",	"\t"),
	("\tnE",	"\t"),
	("\tnA",	"\t"),
	("\tn",	"\t"),
	("\t",		"\t"),
	("\nnuu",	"\n"),
	("\nnu",	"\n"),
	("\nnoo",	"\n"),
	("\nno",	"\n"),
	("\nnii",	"\n"),
	("\nni",	"\n"),
	("\nnee",	"\n"),
	("\nne",	"\n"),
	("\nnau",	"\n"),
	("\nnai",	"\n"),
	("\nnaa",	"\n"),
	("\nna",	"\n"),
	("\nnU",	"\n"),
	("\nnO",	"\n"),
	("\nnI",	"\n"),
	("\nnE",	"\n"),
	("\nnA",	"\n"),
	("\nn",	"\n"),
	("\n",		"\n"),
	("U",		""),
	("Suu",	""),
	("Su",	""),
	("Soo",	""),
	("So",	""),
	("Sii",	""),
	("Si",	""),
	("See",	""),
	("Se",	""),
	("Sau",	""),
	("Sai",	""),
	("Saa",	""),
	("Sa",	""),
	("SU",	""),
	("SO",	""),
	("SI",	""),
	("SE",	""),
	("SA",	""),
	("S",	""),
	("Ruu",	""),
	("Ru",	""),
	("Roo",	""),
	("Ro",	""),
	("Rii",	""),
	("Ri",	""),
	("Ree",	""),
	("Re",	""),
	("Rau",	""),
	("Rai",	""),
	("Raa",	""),
	("Ra",	""),
	("RU",	""),
	("RO",	""),
	("RI",	""),
	("RE",	""),
	("RA",	""),
	("R",	""),
	("O",		""),
	("Nuu",	""),
	("Nu",	""),
	("Noo",	""),
	("No",	""),
	("Nii",	""),
	("Ni",	""),
	("Nee",	""),
	("Ne",	""),
	("Nau",	""),
	("Nai",	""),
	("Naa",	""),
	("Na",	""),
	("NU",	""),
	("NO",	""),
	("NI",	""),
	("NE",	""),
	("NA",	""),
	("N",	""),
	("Luu",	""),
	("Lu",	""),
	("Loo",	""),
	("Lo",	""),
	("Lii",	""),
	("Li",	""),
	("Lee",	""),
	("Le",	""),
	("Lau",	""),
	("Lai",	""),
	("Laa",	""),
	("La",	""),
	("LU",	""),
	("LO",	""),
	("LI",	""),
	("LE",	""),
	("LA",	""),
	("L",	""),
	("I",		""),
	("E",		""),
	("A",		""),
	(" nuu",	" "),
	(" nu",	" "),
	(" noo",	" "),
	(" no",	" "),
	(" nii",	" "),
	(" ni",	" "),
	(" nee",	" "),
	(" ne",	" "),
	(" nau",	" "),
	(" nai",	" "),
	(" naa",	" "),
	(" na",	" "),
	(" nU",	" "),
	(" nO",	" "),
	(" nI",	" "),
	(" nE",	" "),
	(" nA",	" "),
	(" n",	" "),
	(" ",		" "),
};
minc: con '\t';
maxc: con 'z';

sys: Sys;
natural: int;
in, out, err: ref Sys->FD;
hashtab: array of list of (string, string);

ktrans: module
{
	init: fn(nil: ref Draw->Context, nil: list of string);
};

init(nil: ref Draw->Context, nil: list of string)
{
	buf := array[128] of byte;
	bi, ei, nchar, partsent: int;
	mstr: string;
	
	sys = load Sys Sys->PATH;
	in = sys->fildes(0);
	out = sys->fildes(1);
	err = sys->fildes(2);
	bi = ei = partsent = 0;
	natural = 1;
	
	inithtab();
	anjal = nil;
	
	for(;;){
		if(bi >= ei)
			bi = ei = 0;
		else if(ei == len buf-1){
			buf[0:] = buf[bi:ei];
			ei -= bi;
			bi = 0;
		}
		n := sys->read(in, buf[ei:], len buf-ei-1);
		if(n <= 0)
			buf[ei++] = byte '\0';		# to flush buf[bi:ei], if any
		else
			ei += n;
		while(bi < ei){
			if(buf[bi] == byte '\0')
				exit;
			if(sys->utfbytes(buf[bi:], ei-bi) == 0)
				break;
			if(changekbd(buf[bi])){
				bi++;
				continue;
			}
			if(natural || buf[bi]<byte minc || buf[bi]>byte maxc){
				(nil, clen, nil) := sys->byte2char(buf, bi);
				send(buf[bi:], clen);
				bi += clen;
				continue;
			}
			(mstr, nchar) = match(buf[bi:], ei-bi);
			if(mstr != nil){
				if(partsent){
					# deleting the "previous" characters 
					# is not a good idea.  dot (or current window)
					# may have changed without our knowledge.
					send(array[] of {byte '\b', byte '\b'}, partsent);
					partsent = 0;
				}
				send(array of byte mstr, len array of byte mstr);
				if(nchar == 0){		# match, longer possible
					partsent = len mstr;
					break;
				}
				bi += nchar;			# longest possible match found
			}else{
				if(nchar > 0)			# match possible
					break;
				send(buf[bi:], 1);	# no match
				bi++;
			}
		}
	}
}

inithtab()
{
	hashtab = array[maxc-minc+1] of list of (string, string);
	for(j:=len anjal-1; j>=0; j--){
		k := anjal[j].t0[0]-minc;
		hashtab[k] = anjal[j] :: hashtab[k];
	}
}

match(buf: array of byte, lb: int): (string, int)
{
	nc := 0;
	for(h:=hashtab[int buf[0]-minc]; h!=nil; h=tl h){
		map := hd h;
		lt0 := len map.t0;
		n := min(lt0, lb);
		if(map.t0[:n] == (string buf)[:n]){
			if(n == lt0){
				if(nc)
					return(map.t1, 0);
				else
					return(map.t1, lt0);
			}
			nc = n;
		}
	}
	return (nil, nc);
}

send(buf: array of byte, n: int)
{
	if(sys->write(out, buf, n) != n)
		fatal("write error");
}

changekbd(c: byte): int
{
	if(c == byte ''){			# control-k
		natural = !natural;
		return 1;
	}
	return 0;
}

min(m: int, n: int): int
{
	if(m < n)
		return m;
	return n;
}

fatal(s: string)
{
	sys->fprint(err, "ktrans: %s: %r\n", s);
	exit;
}
